home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Linux Cubed Series 2: Applications
/
Linux Cubed Series 2 - Applications.iso
/
math
/
gle-3.000
/
gle-3
/
gle
/
tex.c
< prev
next >
Wrap
C/C++ Source or Header
|
1995-02-07
|
39KB
|
1,624 lines
#include <stdlib.h>
#include <ctype.h>
#include <stdio.h>
#include <string.h>
#include <assert.h>
#ifndef unix
#include <stdarg.h>
#endif
#include "glepro.h"
#define false 0
#define true (!false)
#include "mygraph.h"
#include <math.h>
double emtof(char *s);
int font_reset_parskip(void);
int set_parskip(double v);
int set_lineskip(double v);
int ncat(char *a,char *b,int n);
int pp_fntchar(int f, int c,int32 *out, int *lout);
int polish_eval(char *s, double *x);
int cmd_token(uchar **in,char *cmdstr);
int set_base_size(void);
int find_primcmd(char *cmd);
int text_box(uchar *s,double width,int32 *tbuff, int32 *rplen);
int cmd_param(uchar **inp,uchar *pm[],int pmlen[],int npm);
int text_tomacro(uchar *in, uchar *out);
int texint(char *s, int *i);
int tex_presave(void);
int tex_preload(void);
int fsendstr(char *s, FILE *fout);
int text_gprint(int32 *in,int ilen);
int fftext_block(uchar *s,double width,int justify);
void font_load(void);
int tex_init(void);
int g_get_font(int *i);
int do_prim(uchar **in,int32 *out,int *lout); /* \frac{text}{text} */
#define dbg if ((gle_debug & 1024)>0)
extern int gle_debug;
double text_endx,text_endy;
/*----------------------------------------------------------------------*/
/* TeX Emulation routines */
/*----------------------------------------------------------------------*/
#define FONTDEF extern
#include "font.h"
#include "tex.h"
double linegap;
/*----------------------------------------------------------------------*/
struct def_table_struct {
struct def_table_struct *next;
char *name;
char *defn;
int npm;
};
typedef struct def_table_struct deftable;
/*----------------------------------------------------------------------*/
int tex_def(char *name, char *defn,int npm);
int tex_mathdef(char *name, int defn);
int *tex_findmathdef(char *s);
int tex_chardef(int c, char *defn);
char *tex_findchardef(int c);
deftable *tex_finddef(char *s) ;
/*----------------------------------------------------------------------*/
/* Global variables for TEX emulation */
int fontfam[16][4];
double fontfamsz[16][4]; /* 1=text, 2=script, 3=scriptscript */
int famdef = -1; /* dont use unless/until it is defined */
char *cdeftable[256]; /* Character macro's */
uchar chr_code[256]; /* Character codes 1..9 */
int chr_mathcode[256]; /* Character codes 1..9 */
int chr_val[256]; /* Character values, or macro numbers */
int chr_init; /* Flag to initialize chr variables */
#define dp if (dont_print==false)
int dont_print=0;
int32 gt_pbuff[5000];
int gt_plen;
double gt_l,gt_r,gt_u,gt_d;
int tofont[9] = {0,2,2,1,1,0,0,0,0};
int p_fnt;
double p_hei;
double grphei[10];
int grpfnt[10];
int p_ngrp;
double base_size;
int curstyle=6;
double stretch_factor=1;
/*----------------------------------------------------------------------*/
union both {float f;int32 l;} bth;
#define outlong(v) *(out+((*lout)++)) = v
#define outfloat(v) bth.f = v; *(out+((*lout)++)) = bth.l
#define chrwidth(d) ((*(fnt[p_fnt].chr))[d].wx)
#define tofloat(fff) ((bth.l = fff),bth.f )
#define tolong(fff) ((bth.f = fff),bth.l )
#define checkfont if (fnt[p_fnt].chr==NULL) font_load_metric(p_fnt)
int set_stretch(double v);
set_stretch(double v)
{
stretch_factor = v;
}
set_base_size()
{
g_get_hei(&base_size);
}
text_topcode(uchar *in, int32 *out, int *lout) /* passed a paragraph */
{
int skip_space;
float w;
uchar c,d,c2,d2;
outlong(8); /* set font size */
outfloat(p_hei);
while (c = *(in++)) {
dbg /* if (chr_code[c]>2) */ gprint("uchar %d, code %d value %d \n",c,chr_code[c],chr_val[c]);
switch (chr_code[c]) {
case 10:
case 1: /* Normal character */
d = chr_val[c];
/* if next char is normal, then check for ligature and kern */
norm_again:
w=0;
checkfont;
if (chr_code[*in]==1 || chr_code[*in]==10) {
if (char_lig(p_fnt,&d,chr_val[*in])) {
in++;
goto norm_again;
}
char_kern(p_fnt,d,chr_val[*in],&w);
}
outlong(1);
outlong(d | p_fnt*256);
dbg gprint("==char width %d %f %f \n",d,chrwidth(d),w);
if (fnt[p_fnt].chr==NULL) font_load_metric(p_fnt); outfloat((chrwidth(d)+w)*p_hei);
skip_space = false;
break;
case 2: /* Single space */
if (skip_space) break;
skip_space = true;
outlong(2);
checkfont;
outfloat(fnt[p_fnt].space*p_hei);
outfloat(fnt[p_fnt].space_stretch*p_hei*10*stretch_factor);
outfloat(fnt[p_fnt].space_shrink*p_hei*10);
break;
case 3: /* Tab (for tabular) */
break;
case 4: /* 8Tab (verbatim) */
break;
case 5: /* \\ End of line */
skip_space = false;
outlong(5);
outlong(0); /* space for x,y to be put */
outlong(0);
break;
case 6: /* \ Primitive Command (macro's already done) */
skip_space = false;
do_prim(&in,out,lout);
break;
case 7: /* { begin group */
skip_space = false;
grphei[++p_ngrp] = p_hei;
grpfnt[p_ngrp] = p_fnt;
break;
case 8: /* } end group */
skip_space = false;
if (p_ngrp<1) {
gprint("%s\n",in);
gprint("Too many end group brackets \n");
return;
}
p_hei = grphei[p_ngrp];
p_fnt = grpfnt[p_ngrp--];
font_load_metric(p_fnt);
outlong(8); outfloat(p_hei);
break;
case 9: /* $^_ Macro (Done in macro expansion) */
skip_space = false;
break;
case 11: /* flag for end of paragraph */
skip_space = false;
outlong(10);
outlong(0); /* space for x,y to be put */
outlong(0);
break;
default:
gprint("error, not valid character \n");
}
}
}
/* cmd_param(uchar **inp,char *(*pm)[],int (*pmlen)[],int npm) */
int cmd_param(uchar **inp,uchar *pm[],int pmlen[],int npm)
{
int gcnt=0,i;
uchar *in = *inp;
gcnt = 0;
for (i=0;i<npm;i++) {
pm[i] = in;
pmlen[i] = 0;
if (chr_code[*in]==7) { /* begin group */
pm[i] = ++in;
for (;*in!=0;in++) {
if (chr_code[*in]==7) gcnt++;
if (chr_code[*in]==8) {
if (gcnt==0) break;
gcnt--;
}
}
pmlen[i] = in - pm[i];
in++;
} else {
if (chr_code[*in]==6) { /* backslash look for non-alpha */
pm[i] = ++in;
if (isalpha(*pm[i])) {
for (;*in!=0;in++) {
if (!isalpha(*in)) {
break;
}
}
pmlen[i] = in - pm[i];
} else {
pm[i] = in;
pmlen[i] = 1;
in++;
}
} else {
pm[i] = in;
pmlen[i] = 1;
in++;
}
}
}
*inp = in;
}
text_box(uchar *s,double width,int32 *tbuff, int32 *rplen)
{
uchar *t,*r,*m,*p;
int i;
int plen=0;
char *workbuff;
workbuff = myalloc(1000);
if (s==NULL) return;
if (*s==0) return;
if (chr_init==false) tex_init();
text_tomacro(s,UC workbuff);
plen = 0;
if (width==0) width = 400;
text_topcode(UC workbuff,tbuff,&plen);
text_wrapcode(tbuff,plen,width);
*rplen = plen;
myfree(workbuff);
}
topcode(char *s, int slen, double width, int32 **pbuff, int32 *plen, double *l,double *r,double *u,double *d)
{
char schar;
*pbuff = myalloc(1000);
g_init_bounds();
schar = s[slen];
s[slen] = 0;
text_box(UC s,width,*pbuff,plen);
s[slen] = schar;
g_get_bounds(l,d,r,u);
if (*l > *r) {*l=0; *r=0; *u=0; *d=0;}
}
#define p_sethei(hh) pp_sethei(hh,out,lout)
#define p_hfill(hh) pp_hfill(hh,out,lout)
#define p_move(x,y) pp_move(x,y,out,lout)
#define p_fntchar(ff,cc) pp_fntchar(ff,cc,out,lout)
#define p_mathchar(m) pp_mathchar(m,out,lout)
#define p_pcode(pbuff,plen) pp_pcode(pbuff,plen,out,lout)
pp_move(double x, double y, int32 *out,int *lout)
{
outlong(4);
outfloat(x);
outfloat(y);
}
pp_sethei(double h, int32 *out,int *lout)
{
outlong(8);
outfloat(h);
p_hei = h;
}
pp_hfill(double h, int32 *out,int *lout)
{
outlong(2);
outfloat(0.0);
outfloat(h*p_hei);
outfloat(h*p_hei);
}
int char_bbox_user(int p_fnt,int ix, double *x1,double *y1,double *x2,double *y2);
char_bbox_user(int p_fnt,int ix, double *x1,double *y1,double *x2,double *y2)
{
char_bbox(p_fnt,ix,x1,y1,x2,y2);
*x1 *= p_hei;
*x2 *= p_hei;
*y1 *= p_hei;
*y2 *= p_hei;
}
pp_mathchar(int m, int32 *out, int *lout)
{
int mchar,mfam,mtyp;
int ix;
double x1,y1,x2,y2,reqhi,yc;
double oldhei;
oldhei = p_hei;
mchar = m & 0xff;
mfam = (m & 0xf00) / 0x100;
mtyp = (m & 0xf000) / 0x1000;
if (mtyp == 7 && famdef>=0) mfam = famdef;
if (mtyp == 7) mtyp = 0;
ix = 'b'; /* center on letter b */
char_bbox_user(p_fnt,ix,&x1,&y1,&x2,&y2);
reqhi = y2/2;
p_sethei(fontfamsz[mfam][tofont[curstyle]] * p_hei);
char_bbox_user(fontfam[mfam][tofont[curstyle]],mchar,&x1,&y1,&x2,&y2);
yc = (y2-y1)/2;
if (mtyp==1) pp_move(0,reqhi+yc-y2,out,lout);
p_fntchar(fontfam[mfam][tofont[curstyle]],mchar);
if (mtyp==1) pp_move(0,-(reqhi+yc-y2),out,lout);
p_sethei(oldhei);
}
#define mchrwidth(ddd) ((*(fnt[ff].chr))[ddd].wx)
pp_fntchar(int ff, int ch, int32 *out,int *lout)
{
if (fnt[ff].chr==NULL) font_load_metric(ff);
outlong(1);
if (ch==0) ch = 254;
outlong(ch | ff*256);
outfloat((mchrwidth(ch))*p_hei);
}
pp_pcode(int32 *pbuff, int plen, int32 *out,int *lout)
{
int i;
out += *lout;
for (i=0;i<plen;i++) *out++ = *pbuff++;
*lout = *lout + plen;
}
cmd_param1(uchar **in,char *str1)
{
union {char *s[4]; uchar *u[4];} pm;
int pmlen[4];
cmd_param(in,pm.u,pmlen,1);
ncpy(str1,pm.s[0],pmlen[0]);
}
cmd_param2(uchar **in,char *str1,char *str2)
{
union {char *s[4]; uchar *u[4];} pm;
int pmlen[4];
cmd_param(in,pm.u,pmlen,(int) 2);
ncpy(str1,pm.s[0],pmlen[0]);
ncpy(str2,pm.s[1],pmlen[1]);
}
cmd_param3(uchar **in,char *str1,char *str2,char *str3)
{
union {char *s[5]; uchar *u[5];} pm;
int pmlen[5];
cmd_param(in,pm.u,pmlen,3);
ncpy(str1,pm.s[0],pmlen[0]);
ncpy(str2,pm.s[1],pmlen[1]);
ncpy(str3,pm.s[2],pmlen[2]);
}
do_prim(uchar **in,int32 *out,int *lout) /* \frac{text}{text} */
{
int ci;
int ix,savefnt,newfnt;
static char cmdstr[20];
char str1[100],str2[100],str3[100];
double lef,wid,hei,dep,savehei,x;
int32 *pbuff=0;
int32 plen;
union {char *s[10]; uchar *u[10];} pm;
int pmlen[10];
int *m,i,k,j,n,npm;
k = 0;
cmd_token(in,cmdstr); /* finds command name and parameters */
ci = find_primcmd(cmdstr);
if (ci==0) { /* then maybe its a mathchar */
m = tex_findmathdef(cmdstr);
if (m!=0) {
p_mathchar(*m);
} else {
gprint("Unrecognised control sequence {%s} \n",cmdstr);
}
return;
}
switch (ci) {
case tp_sup: /* \superscript{exp} */
cmd_param(in,pm.u,pmlen,1);
savehei = p_hei;
p_hei = p_hei * .7;
topcode(pm.s[0],pmlen[0],0.0,&pbuff,&plen,&lef,&wid,&hei,&dep);
p_move(0,0.8*p_hei);
p_pcode(pbuff,plen);
p_move(0,-0.8*p_hei);
myfree(pbuff);
p_sethei(savehei);
break;
case tp_sub:
cmd_param(in,pm.u,pmlen,1);
savehei = p_hei;
p_hei = p_hei * .7;
topcode(pm.s[0],pmlen[0],0.0,&pbuff,&plen,&lef,&wid,&hei,&dep);
p_move(0,-0.3*p_hei);
p_pcode(pbuff,plen);
p_move(0,0.3*p_hei);
myfree(pbuff);
p_sethei(savehei);
break;
case tp_sethei: /* \sethei{exp} */
cmd_param1(in,str1);
p_sethei(emtof(str1));
break;
case tp_hfill: /* \sethei{exp} */
p_hfill(10.0);
break;
case tp_char:
cmd_param1(in,str1);
texint(str1,&ix);
p_fntchar(p_fnt,ix);
break;
case tp_chardef: /* /chardef{a}{xxxxx} */
cmd_param2(in,str1,str2);
tex_chardef(str1[0],str2);
break;
case tp_ssfont:
k++;
case tp_sfont:
k++;
case tp_tfont: /* \tfont{0}{cmr10}{.5} */
cmd_param3(in,str1,str2,str3);
i = atoi(str1); if (i>15) i = 1;
fontfam[i][k] = pass_font(str2);
fontfamsz[i][k] = emtof(str3);
break;
case tp_accent: /* accent{texcmr}{123}{a} */
{
double wid2,hei2,lef2,dep2,ww,hh,h=0,cwid,cwid2;
int ix2;
cmd_param3(in,str1,str2,str3);
savefnt = p_fnt;
newfnt = pass_font(str1);
texint(str2,&ix);
ix2 = str3[0];
char_bbox(newfnt,ix,&lef,&dep,&wid,&hei);
cwid = p_hei * ((*(fnt[newfnt].chr))[ix].wx);
char_bbox(p_fnt,ix2,&lef2,&dep2,&wid2,&hei2);
cwid2 = p_hei * ((*(fnt[p_fnt].chr))[ix2].wx);
wid *= p_hei; wid2 *= p_hei; hei *= p_hei; hei2 *= p_hei;
lef *= p_hei; dep *= p_hei;
lef2 *= p_hei; dep2 *= p_hei;
if (hei2>p_hei*(3.6/8.0)) h = hei2-p_hei*(3.6/8.0);
ww = lef2+wid2;
p_fntchar(p_fnt,ix2);
p_move(-cwid2 + lef2 + wid2/2 -wid/2,h); /* cwid2/2 - cwid/2 */
p_fntchar(newfnt,ix); /* cwid2/2 + cwid/2 */
p_move(-cwid + cwid2 - lef2 - wid2/2 + wid/2,-h);
p_fnt = savefnt;
font_load_metric(p_fnt);
break;
}
case tp_def:
cmd_param1(in,str1); /* finds everything up to the #1#2 */
npm = 0;
while (**in == '#') {
(*in)++;
n = (*(*in)++) - '0';
if (n>0 && n<9) if (npm<n) npm=n;
}
cmd_param1(in,str2);
tex_def(str1,str2,npm);
break;
case tp_mathchardef: /* /mathchardef */
cmd_param2(in,str1,str2);
texint(str2,&ix);
tex_mathdef(str1+1,ix);
break;
case tp_movexy:
cmd_param2(in,str1,str2);
p_move(emtof(str1),emtof(str2));
break;
case tp_rule:
cmd_param2(in,str1,str2);
outlong(6);
outfloat(emtof(str1));
outfloat(emtof(str2));
break;
case tp_mathchar:
cmd_param1(in,str1);
texint(str1,&ix);
p_mathchar(ix);
break;
case tp_mathcode:
cmd_param2(in,str1,str2);
texint(str2,&ix);
chr_mathcode[*str1] = ix;
break;
case tp_delcode:
cmd_param2(in,str1,str2);
texint(str2,&ix);
chr_mathcode[*str1] = ix;
break;
case tp_setfont:
cmd_param1(in,str1);
p_fnt = pass_font(str1);
font_load_metric(p_fnt);
if (fnt[p_fnt].chr==NULL) font_load_metric(p_fnt);
break;
case tp_presave:
gprint("Saving definitions\n");
tex_presave();
break;
case tp_newline:
outlong(5);
outlong(0); /* space for x,y to be put */
outlong(0);
break;
case tp_parskip:
cmd_param1(in,str1);
set_parskip(emtof(str1));
break;
case tp_setstretch:
cmd_param1(in,str1);
set_stretch(emtof(str1));
break;
case tp_lineskip:
cmd_param1(in,str1);
set_lineskip(emtof(str1));
break;
case tp_linegap:
cmd_param1(in,str1);
linegap = emtof(str1);
break;
case tp_frac:
case tp_delimiter:
case tp_left:
case tp_right:
case tp_defbegin:
case tp_nolimits:
case tp_overbrace:
case tp_overline:
case tp_underbrace:
case tp_underline:
gprint("A valid GLE-TEX primitive which isn't implemented yet %d \n",ci);
break;
default:
gprint("An invalid GLE-TEX primitive %d \n",ci);
break;
}
}
#ifndef DJ
double emtof(char *s)
{ /* same as ATOF but if it sees EM then it multiplies by FONT HEI */
if (strstr(s,"sp")!=NULL) {
return atof(s)*fnt[p_fnt].space*p_hei;
}
if (strstr(s,"em")!=NULL) {
return atof(s)*p_hei*.75;
}
return atof(s);
}
#else
double emtof(char *s)
{ /* same as ATOF but if it sees EM then it multiplies by FONT HEI */
/* GLE32 doesn't interpret "-1em" but "-1 em" a.r. */
char *ss; /* is it allowed to overwrite s? */
double ret;
ss = (char *) malloc((strlen(s)+1)*sizeof(char));
strcpy(ss,s);
if (strstr(ss,"sp")!=NULL) {
*strstr(ss,"sp") = '\0';
ret = atof(ss)*fnt[p_fnt].space*p_hei;
free(ss);
return ret;
}
if (strstr(ss,"em")!=NULL) {
*strstr(ss,"em") = '\0';
ret = atof(ss)*p_hei*.75;
free(ss);
return ret;
}
ret = atof(ss);
free(ss);
return ret;
}
#endif
texint(char *s, int *i) /* Reads an integer, or hex string (if $) */
{
int32 j;
if (*s=='$') {
sscanf(s+1,"%lx",&j);
*i = j;
} else *i = atoi(s);
}
/*
Character Codes
a..z 1 normal character
space 2 single space
<TAB>,& 3 Tab (as in tabular)
<8TAB> 4 TAB (as in verbatim)
<LF>,\\ 5 End of line
\ 6 Macro or command
{ 7 Begin group
} 8 end group
$_^ 9 Macro call
10 null
255 11 end of paragraph (crcr)
end of command, = first non alpha character
*/
/* Bounding Box ??
1=char font+char,x
2=move x,stret,shrink throw away after cr
3=MOVE x,0,0 glue which has been set
4=MOVE x,y solid move
5=newline,x,y
6=rule x,y
10=color color
8=fontsz fontsz
9=font i
15=null
*/
#define infloat(fff) ((bth.l = fff),bth.f)
text_wrapcode(int32 *in,int ilen,double width)
{
double cx=0,cy=0,p_hei,ax=0,x,y,cdep=0,chei=0;
int i,j,eat_glue,c,p_fnt,si,skline,saveii;
double totstretch=0,totshrink=0,ls=0,gap=0
,last_y,last_x,lastdep,last_stret,last_shrink;
int32 *pcr=0,last_space=0;
double setlen;
dbg text_gprint(in,ilen);
ls = 0;
last_x = 0;
gap = 0;
last_y = 0;
lastdep = 0;
last_stret = 0;
last_shrink = 0;
dbg gprint("==wrap pcode, ilen = %d \n",ilen);
dbg gprint("wrap pcode ilen=%d \n",ilen);
p_hei = 1;
si = 0;
for (i=0;i<ilen;i++) {
switch (*(in+i)) {
case 1: /* char font+char,wx */
eat_glue = false;
p_fnt = (*(in+ ++i) & 0xff00) / 0x100;
font_load_metric(p_fnt);
c = *(in+i) & 0x00ff;
if (cdep>cy+p_hei*((*(fnt[p_fnt].chr))[c].y1))
cdep=cy+p_hei*((*(fnt[p_fnt].chr))[c].y1);
if (chei<cy+p_hei*((*(fnt[p_fnt].chr))[c].y2))
chei=cy+p_hei*((*(fnt[p_fnt].chr))[c].y2);
/* gprint("chei=%f, cdep=%f \n",chei,cdep); */
cx += tofloat(*(in+ ++i));
ax = cx;
if (cx>width) {
if (last_space>si) {
dbg gprint("Call SET_GLUE from %d, to %d \n",si,last_space);
set_glue(in+si,last_space-si,last_x,width,last_stret,last_shrink,&setlen);
i = last_space;
*(in+i++) = 4;
*(in+i++) = tolong(-setlen);
if (pcr!=NULL) { /* put in last line feed now */
y = last_y-ls;
if ((y+chei+gap)>lastdep)
y = lastdep-chei-gap;
cy = y;
*pcr = tolong(y);
}
font_get_lineskip(&ls,&gap);
pcr = (in+i++); /* place to put line feed */
*(in+i) = 20; /* null */
last_stret = 0;
last_shrink = 0;
totstretch = 0;
totshrink = 0;
lastdep = cdep;
last_y = cy;
cx = 0;
cy = 0;
si = i;
eat_glue = true;
}
}
break;
case 2: /* move x,stretch,shrink */
last_space = i;
last_x = ax;
last_y = cy;
last_stret = totstretch;
last_shrink = totshrink;
if (eat_glue) {*(in+i)=3; *(in+ ++i)=tolong(0);i+=2;break;}
cx += tofloat(*(in+ ++i));
totstretch += tofloat(*(in+ ++i));
totshrink += tofloat(*(in+ ++i));
dbg gprint("total stretch %f, shrink %f \n",totstretch,totshrink);
break;
case 3: /* move x,0,0 SOLID */
cx += tofloat(*(in+ ++i));
i += 2;
ax = cx;
eat_glue = false;
break;
case 4: /* move x,y SOLID */
eat_glue = false;
cx += tofloat(*(in+ ++i));
cy += tofloat(*(in+ ++i));
ax = cx;
break;
case 5: /* Newline x,y (0,0 at moment) */
case 10:
if (*(in+i)==5) skline = true; else skline = false;
*(in+i) = 0;
/* last_space = i;
last_x = ax;
last_y = cy;
last_stret = totstretch;
last_shrink = totshrink;
*/
if (last_space<=si || ax==cx) {
last_x = ax;
last_y = cy;
last_stret = totstretch;
last_shrink = totshrink;
last_space = i;
}
dbg gprint("Call SET_GLUE from %d, to %d \n",si,last_space);
set_glue(in+si,last_space-si,last_x,width,last_stret,last_shrink,&setlen);
saveii = i;
i = last_space;
while (i < saveii) *(in+i++) = 20; /* nop */
*(in+i++) = 4;
*(in+i++) = tolong(-setlen);
if (pcr!=NULL) { /* put in last line feed now */
y = last_y-ls;
if ((y+chei+gap)>lastdep)
y = lastdep-chei-gap;
cy = y;
*pcr = tolong(y);
}
if (skline)
font_get_lineskip(&ls,&gap);
else font_get_parskip(&ls,&gap);
pcr = (in+i); /* place to put line feed */
last_stret = 0;
last_shrink = 0;
totstretch = 0;
totshrink = 0;
lastdep = cdep;
last_y = cy;
cx = 0;
cy = 0;
si = i+1;
eat_glue = true;
break;
/* eat_glue = true;
i += 2;
break; */
case 6: /* rule x,y */
i += 2;
eat_glue = false;
break;
case 7: /* color color */
g_set_color(tofloat(*(in+ ++i)));
break;
case 8: /* fontsz sz */
p_hei = tofloat(*(in+ ++i));
g_set_hei(p_hei);
break;
case 9: /* font p_fnt */
p_fnt = *(in+ ++i);
font_load_metric(p_fnt);
break;
case 20: /* nop */
break;
default:
gprint("dud pcode in wrap pcode %d i=%d \n",*(in+i),i);
break;
}
}
if (last_space==0) last_space = ilen;
dbg gprint("Exiting call to SET_GLUE from %d, to %d \n",si,last_space);
set_glue(in+si,last_space-si,last_x,width,last_stret,last_shrink,&setlen);
if (pcr!=NULL) { /* put in last line feed now */
y = last_y-ls;
if ((y+chei+gap)>lastdep)
y = lastdep-chei-gap;
cy = y;
*pcr = tolong(y);
}
dbg text_gprint(in,ilen);
}
set_glue(int32 *in,int ilen,double actual,double width,double stretch,double
shrink,double *setlen)
{
double mst=0,msh=0;
float s1,s2,x,y;
int i=0;
dbg gprint("===set glue \n");
dbg text_gprint(in,ilen);
dbg gprint("set glue ilen=%d actual=%f, width=%f, stretch=%f shrink=%f \n"
,ilen,actual,width,stretch,shrink);
/* if (actual<0) get_natural(in,ilen,&actual); */
if (actual<width) {
if (stretch>0.0000001) mst = (width-actual)/stretch;
msh = 0;
if (mst>1) mst=0;
} else {
mst = 0;
if (shrink>0) msh = (actual-width)/shrink;
if (msh>1) msh=0;
}
*setlen = actual+stretch*mst+shrink*msh;
dbg gprint("SETTing glue to %f %f actual %f, setto %f\n",mst,msh,actual,*setlen);
for (i=0;i<ilen;i++) {
switch (*(in+i)) {
case 1: /* char font+char,wx */
i += 2;
break;
case 2: /* move x,stretch,shrink */
x = tofloat(*(in+i+1));
s1 = tofloat(*(in+i+2));
s2 = tofloat(*(in+i+3));
*(in+i) = 3;
*(in+i+1) = tolong(x + s1*mst+s2*msh);
i += 3;
break;
case 3: /* move x,0,0 SOLID */
i += 3;
break;
case 4: /* move x,y SOLID */
i += 2;
break;
case 5: /* Newline x,y (0,0 at moment) */
i += 2;
break;
case 6: /* rule x,y */
i += 2;
break;
case 7: /* color color */
i += 1;
break;
case 8: /* fontsz sz */
i += 1;
break;
case 9: /* font p_fnt */
i += 1;
break;
case 10: /* Newparagraph x,y (0,0 at moment) */
i += 2;
break;
case 20: /* nop */
break;
default:
gprint("dud (in set glue) pcode in text pcode %d i=%d\n",*(in+i),i);
break;
}
}
dbg printf("=== Result after setting \n");
dbg text_gprint(in,ilen);
dbg printf("===+++++ END OF SET GLUE =============== \n");
}
text_draw(int32 *in,int ilen)
{
double cx,cy,p_hei,x,y;
int i,c,p_fnt;
dbg gprint("---TEXT DRAW, ilen = %d \n",ilen);
dbg text_gprint(in,ilen);
cx = 0;
cy = 0;
dp g_get_xy(&cx,&cy);
dbg printf("Current x y, %g %g \n",cx,cy);
p_hei = 1;
for (i=0;i<ilen;i++) {
switch (*(in+i)) {
case 1: /* char font+char,wx */
p_fnt = (*(in+ ++i) & 0xff00) / 0x100;
font_load_metric(p_fnt);
c = *(in+i) & 0x00ff;
g_set_bounds(cx+p_hei*((*(fnt[p_fnt].chr))[c].x1),cy+p_hei*((*(fnt[p_fnt].chr))[c].y1));
g_set_bounds(cx+p_hei*((*(fnt[p_fnt].chr))[c].x2),cy+p_hei*((*(fnt[p_fnt].chr))[c].y2));
dp {
g_move(cx,cy);
g_char(p_fnt,c);
}
cx += tofloat(*(in+ ++i));
break;
case 2: /* move x,stretch,shrink */
cx += tofloat(*(in+ ++i));
i += 2; /* glue is already set */
break;
case 3: /* move x,0,0 SOLID */
cx += tofloat(*(in+ ++i));
i += 2;
break;
case 4: /* move x,y SOLID */
cx += tofloat(*(in+ ++i));
cy += tofloat(*(in+ ++i));
break;
case 5: /* Newline x,y (turned into a move) */
i += 2;
break;
case 6: /* rule x,y */
x = tofloat(*(in+ ++i));
y = tofloat(*(in+ ++i));
g_set_bounds(cx,cy);
g_set_bounds(cx+x,cy+y);
if (x>0) g_box_fill(cx,cy,cx+x,cy+y);
break;
case 7: /* color color */
/* dp g_set_color(tofloat(*(in+ ++i)));*/
break;
case 8: /* fontsz sz */
p_hei = tofloat(*(in+ ++i));
g_set_hei(p_hei);
break;
case 9: /* font p_fnt */
p_fnt = *(in+ ++i);
font_load_metric(p_fnt);
break;
case 10: /* Newline x,y (turned into a move) */
i += 2;
break;
case 20: /* nop */
break;
case 0:
dbg gprint("zero");
break;
default:
gprint("dud3 pcode in text pcode %d %d \n",*(in+i),i);
break;
}
}
text_endx = cx;
text_endy = cy;
dbg gprint("---TEXT DRAW, DONE. %g %g \n",cx,cy);
}
double tex_xend(void)
{
return text_endx;
}
double tex_yend(void)
{
return text_endy;
}
text_gprint(int32 *in,int ilen)
{
double cx,cy,p_hei,x,y;
int i,c,p_fnt,z;
for (i=0;i<ilen;i++) printf("%lx ",*(in+i));
printf("\n");
z=0;
printf("# ");
for (i=0;i<ilen;i++) {
switch (*(in+i)) {
case 1: /* char font+char,wx */
p_fnt = (*(in+ ++i) & 0xff00) / 0x100;
font_load_metric(p_fnt);
c = *(in+i) & 0x00ff;
x = tofloat(*(in+ ++i));
printf("%c[%3.3h]",c,x);
/* printf("%c{%d %3.3f} ",c,p_fnt,tofloat(*(in+ ++i))); */
break;
case 2: /* move x,stretch,shrink */
printf("[sp %3.3f %3.3f %3.3f] \n# ",tofloat(*(in+1+i))
,tofloat(*(in+2+i)),tofloat(*(in+3+i)));
i += 3;
break;
case 3: /* move x,0,0 SOLID */
printf("(3 %3.3f %3.3f %3.3f) \n# ",tofloat(*(in+1+i))
,tofloat(*(in+2+i)),tofloat(*(in+3+i)));
i += 3;
break;
case 4: /* move x,y SOLID */
printf("(4 %3.3f %3.3f) \n# ",tofloat(*(in+1+i))
,tofloat(*(in+2+i)));
i += 2;
break;
case 5: /* Newline x,y (turned into a move) */
i += 2;
printf("5 \n# ");
break;
case 6: /* rule x,y */
printf("(rule %3.3f %3.3f) \n# ",tofloat(*(in+1+i))
,tofloat(*(in+2+i)));
i += 2;
break;
case 7: /* color color */
printf("(color %x) \n# ",(*(in+ ++i)));
break;
case 8: /* fontsz sz */
printf("(p_hei %3.3f) \n# ",tofloat(*(in+ ++i)));
break;
case 9: /* font p_fnt */
printf("(font %d) \n",(*(in+ ++i)));
break;
case 10: /* Newline x,y (turned into a move) */
i += 2;
printf("\n10(paragraph)\n# ");
break;
case 20: /* nop */
printf("NOP ");
break;
default:
printf("(err=%4x pos=%d)\n ",*(in+i),i);
break;
}
}
printf("\n");
}
double lineskip1,parskip1;
font_reset_parskip()
{
lineskip1 = 1.0;
parskip1 = 2.5;
}
set_parskip(double v)
{
parskip1 = v;
}
set_lineskip(double v)
{
lineskip1 = v;
}
font_get_lineskip(double *ls,double *gap)
{
*ls = p_hei * lineskip1;
*gap = *ls * .1 + linegap;
}
font_get_parskip(double *ls,double *gap)
{
*ls = p_hei * parskip1;
*gap = *ls * .1;
}
int pass_font(char *p)
{
int i,f=0,etype=1;
int32 j;
char u[90];
char vv[80],*s;
double xx;
s = &u[0];
strncpy(u,p,90);
strupr(u);
if ( (*s=='"') || (strchr(s,'$') != NULL)) {
strcpy(vv,"cvtfont(");
strcat(vv,s); strcat(vv,")");
polish_eval(vv,&xx);
memcpy(&j,&xx,sizeof(int32));
return j; /* actyally is an int */
} else {
if (nfnt==0) font_load();
for (i=1; i<=nfnt; i++) {
if (fnt[i].name!=NULL) if (strcmp(fnt[i].name,u)==0) {
return i;
}
}
gprint("Invalid font name {%s}, NFNT %d expecting one of: \n ",u,nfnt);
for (i=1;i<=nfnt; i++) {
if (fnt[i].name!=NULL)
gprint(" {%s} ",fnt[i++].name);
if (fnt[i].name!=NULL)
gprint(" {%s} ",fnt[i++].name);
if (fnt[i].name!=NULL)
gprint(" {%s} ",fnt[i++].name);
if (fnt[i].name!=NULL)
gprint(" {%s} \n",fnt[i].name);
}
return 1; /* default font number */
}
}
#define get_exps(ss) polish(ss,(char *) pcode,plen,&etype)
#define tok(n) (*tk)[n]
get_font(char (*(*tk)[500]),int *ntok,int *curtok,int32 *pcode,int *plen)
{
int i,f=0,etype=1;
char vv[80];
char *p;
if (nfnt==0) font_load();
if ( (*tok(*curtok)=='"') || (strchr(tok(*curtok),'$') != NULL) ) {
strcpy(vv,"cvtfont(");
strcat(vv,tok(*curtok)); strcat(vv,")");
get_exps(vv);
(*curtok)++;
return;
}
p = (*tk)[*curtok];
(*curtok)++;
*(pcode+(*plen)++) = 8;
for (i=1; i<=nfnt; i++) {
if (fnt[i].name!=NULL) if (strcmp(fnt[i].name,p)==0) {
*(pcode+(*plen)++) = i; /* font number */
return;
}
}
gprint("Invalid font name {%s}, expecting one of: \n ",p);
for (i=1;i<=nfnt; i++) {
if (fnt[i].name!=NULL)
gprint(" {%s} ",fnt[i++].name);
if (fnt[i].name!=NULL)
gprint(" {%s} ",fnt[i++].name);
if (fnt[i].name!=NULL)
gprint(" {%s} ",fnt[i++].name);
if (fnt[i].name!=NULL)
gprint(" {%s} \n",fnt[i].name);
}
*(pcode+(*plen)++) = 1; /* default font number */
}
text_block(uchar *s,double width,int justify)
{
double ox,oy,x,y,ll,rr,uu,dd;
double a,b,c,d;
set_base_size();
g_get_bounds(&a,&b,&c,&d);
g_init_bounds();
dont_print = true;
fftext_block(s,width,justify);
dont_print = false;
g_get_bounds(&ll,&dd,&rr,&uu);
if (ll > rr) {ll=0; rr=0; uu=0; dd=0;}
g_get_xy(&ox,&oy);
x = ox; y = oy;
g_dotjust(&x,&y,ll,rr,uu,dd,justify);
g_move(x,y);
g_init_bounds();
if (a<=c) {
g_set_bounds(a,b);
g_set_bounds(c,d);
}
g_get_bounds(&a,&b,&c,&d);
text_draw(gt_pbuff,gt_plen);
g_get_bounds(&a,&b,&c,&d);
g_move(ox,oy);
}
/*----------------------------------------------------------------------*/
/* Searches CMD and replaces #n's with parameters */
char *tex_replace(char *cmd,char *pm[],int pmlen[],int npm)
{
char *r,*s,*o;
int n,i;
/* printf("replace {%s} \n",cmd);
for (i=0;i<npm;i++) {
printf("pm[%d] = {%s} %d \n",i,pm[i],pmlen[i]);
}
*/
if (strchr(cmd,'#')==0) return sdup(cmd);
r = myalloc(1000);
o = r;
for (s=cmd; *s!=0; s++) {
if (*s=='#') {
n = *(++s) - '0';
if (n>0 && n<=npm) {
strncpy(o,pm[n-1],pmlen[n-1]);
o += pmlen[n-1];
}
} else *o++ = *s;
}
*o++ = 0;
return r;
}
/*----------------------------------------------------------------------*/
/* tex_chardef */
/*----------------------------------------------------------------------*/
tex_chardef(int c, char *defn) /* Defines single char as string */
{
if (c<0 || c>255) return;
if (cdeftable[c]!=NULL) myfree(cdeftable[c]);
cdeftable[c] = sdup(defn);
}
char *tex_findchardef(int c)
{
return cdeftable[c];
}
/*----------------------------------------------------------------------*/
/* Hashing table code for \def */
/*----------------------------------------------------------------------*/
#define HASHSIZE 101
static deftable *def_hashtab[HASHSIZE];
unsigned hash_str(char *s);
unsigned hash_str(char *s)
{
unsigned hashval;
for (hashval=0; *s != 0; s++)
hashval = *s + 31*hashval;
return hashval % HASHSIZE ;
}
deftable *tex_finddef(char *s)
{
deftable *np;
for (np = def_hashtab[hash_str(s)]; np != NULL; np = np->next)
if (strcmp(s, np->name) == 0) {
return np;
}
return NULL;
}
tex_def(char *name, char *defn,int npm)
{
deftable *np;
char **s;
unsigned hashval;
if ((np = tex_finddef(name)) == NULL) { /* not found */
np = (deftable *) myalloc(sizeof(*np));
if ((np == NULL) || (np->name = sdup(name)) == NULL)
return NULL;
hashval = hash_str(name);
np->next = def_hashtab[hashval];
def_hashtab[hashval] = np;
np->npm = npm;
if ((np->defn = sdup(defn)) == NULL) return NULL;
} else {
myfree(np->defn);
if ((np->defn = sdup(defn)) == NULL) return NULL;
}
return true;
}
/*----------------------------------------------------------------------*/
/* Hashing table code for \mathchardef */
/*----------------------------------------------------------------------*/
struct mdef_table_struct {
struct mdef_table_struct *next;
char *name;
int defn;
};
typedef struct mdef_table_struct mdeftable;
static mdeftable *mdef_hashtab[HASHSIZE];
int *tex_findmathdef(char *s)
{
mdeftable *np;
for (np = mdef_hashtab[hash_str(s)]; np != NULL; np = np->next)
if (strcmp(s, np->name) == 0) {
return &np->defn;
}
return NULL;
}
tex_mathdef(char *name, int defn)
{
mdeftable *np;
int *d;
unsigned hashval;
if ((d = tex_findmathdef(name)) == NULL ) { /* not found */
np = (mdeftable *) myalloc(sizeof(*np));
if ((np == NULL) || (np->name = sdup(name)) == NULL)
return NULL;
hashval = hash_str(name);
np->next = mdef_hashtab[hashval];
mdef_hashtab[hashval] = np;
np->defn = defn;
} else {
*d = defn;
}
return true;
}
tex_init()
{
int i;
for (i=0;i<256;i++) chr_val[i]=i;
for (i=0;i<256;i++) chr_code[i]=10; /* other */
for (i=65;i<91;i++) chr_code[i]=1; /* alpha */
for (i=97;i<123;i++) chr_code[i]=1;
chr_code[0] = 2; /* maybe should be 0, this is only tested in lig*/
chr_code[' '] = 2;
chr_code[9] = 2;
chr_code['\n'] = 2;
chr_code['\\'] = 6;
chr_code['{'] = 7;
chr_code['}'] = 8;
chr_code[255] = 11; /* flag for end of paragraph, unless verbatim */
chr_init = true;
tex_preload();
tex_def(" ","\\movexy{1sp}{}",0);
tex_def("\\","\\newline",0);
tex_def("{","\\char{123}",0);
tex_def("}","\\char{125}",0);
tex_def("_","\\char{95}",0);
/* tex_def("^","\\char{94}",0); */
tex_def("$","\\char{36}",0);
}
tex_clear()
{
/* clear CHARDEF table before each redraw */
int c;
for (c=1;c<255;c++) {
if (cdeftable[c]!=NULL) {
myfree(cdeftable[c]);
cdeftable[c] = NULL;
}
}
tex_chardef('^',"\\sup ");
tex_chardef('_',"\\sub ");
}
g_measure(char *s, double *l, double *r, double *u, double *d)
{
double sa,sb,sc,sd;
g_get_bounds(&sa,&sb,&sc,&sd);
set_base_size();
g_init_bounds();
dont_print = true;
fftext_block(UC s,0.0,0);
dont_print = false;
g_get_bounds(l,d,r,u);
if (*l > *r) {*l=0; *r=0; *u=0; *d=0;}
gt_l = *l;
gt_r = *r;
gt_u = *u;
gt_d = *d;
g_init_bounds();
if (sa>sc) return;
g_set_bounds(sa,sb);
g_set_bounds(sc,sd);
}
g_textfindend(char *s, double *cx, double *cy)
{
double sa,sb,sc,sd;
set_base_size();
g_get_bounds(&sa,&sb,&sc,&sd);
dont_print = true;
fftext_block(UC s,0.0,0);
*cx = text_endx;
*cy = text_endy;
dont_print = false;
g_init_bounds();
if (sa>sc) return;
g_set_bounds(sa,sb);
g_set_bounds(sc,sd);
}
g_jtext(int just)
{
double ox,oy,x,y;
g_get_xy(&ox,&oy);
x = ox; y = oy;
g_dotjust(&x,&y,gt_l,gt_r,gt_u,gt_d,just);
g_move(x,y);
text_draw(gt_pbuff,gt_plen);
g_move(ox,oy);
}
static uchar tbuff[8000];
text_def(uchar *s)
{
gt_plen = 0;
if (chr_init==false) tex_init();
text_topcode(s,gt_pbuff,>_plen);
}
fftext_block(uchar *s,double width,int justify)
{
uchar *t,*r,*m,*p;
int i;
g_get_font(&p_fnt);
font_load_metric(p_fnt);
g_get_hei(&p_hei);
font_reset_parskip();
gt_plen = 0;
if (s==NULL) {
dbg gprint("TEXT_BLOCK, Passed NULL pointer \n");
return;
}
if (*s==0) {
/* gprint("TEXT_BLOCK, Passed empty string \n"); */
return;
}
if (chr_init==false) tex_init();
lp:
t = UC strstr(SC s,"\n\n"); /* search for cr,cr */
if (t!=NULL) {
*(t+1) = 255; /* flag end of paragraph */
goto lp;
}
text_tomacro(s,tbuff);
gt_plen = 0;
if (width==0) {
width = 400;
chr_code['\n'] = 5;
} else chr_code['\n'] = 2;
text_topcode(tbuff,gt_pbuff,>_plen);
text_wrapcode(gt_pbuff,gt_plen,width);
text_draw(gt_pbuff,gt_plen);
g_set_font(p_fnt);
g_set_hei(p_hei);
/* dbg gprint("text to macro {%s} {%s} \n",s,tbuff);
dbg gprint("============topcode \n");
dbg gprint("P: ");
for (i=0;i<plen;i++) {
dbg gprint("%4x ",pbuff[i]);
if ((i+1)/10==(i+1)/10.0) dbg gprint("\nP: ");
}
dbg gprint("\n");
dbg text_gprint(pbuff,plen);
dbg gprint("\n");
dbg gprint("==== ==== ==== ==== wrapcode \n");
dbg gprint("\n");
dbg gprint("==== ==== ==== ==== draw \n");
*/
}
cmd_token(uchar **in,char *cmdstr)
{
int gcnt,i;
char *s;
s = cmdstr;
i=0;
if ( (!isalpha(**in)) && (**in != 0)) {
*cmdstr++ = *(*in)++;
} else {
for (; chr_code[**in]==1 && **in != 0 && i<20;(*in)++,i++) {
*cmdstr++ = **in;
}
}
*cmdstr = 0;
cmdstr -= 1;
if (chr_code[*cmdstr]==1) {
for (;(**in != 0) && (chr_code[**in]==2);) (*in)++;
}
}
text_tomacro(uchar *in, uchar *out)
{
/* find /cmdname or defined characters */
static char macroname[30];
uchar *s,*dfn,*r,*saves;
int changed,dlen;
int nrep,j;
deftable *np;
static union {char *s[10]; uchar *u[10];} pm;
static int pmlen[10];
nrep = 0;
strcpy(SC out,SC in);
for (s=out; *s != 0;s++) {
if (nrep>300) gle_abort("Loop in text macros\n");
if (chr_code[*s]==6) { /* backslash, begining of macro? */
saves = s;
s++;
cmd_token(&s,macroname);
np = tex_finddef(macroname);
if (np != NULL) {
nrep++;
dfn = UC np->defn;
dbg printf("Found macro {%s} = {%s} \n",macroname,dfn);
cmd_param(&s,pm.u,pmlen,np->npm);
dlen = s-saves;
r = UC tex_replace(SC dfn,pm.s,pmlen,np->npm);
s = saves;
memmove(SC s+strlen(SC r),SC s+dlen,strlen(SC s)+1);
strncpy(SC s,SC r,strlen(SC r));
myfree(r);
s--;
}
s = saves;
}
if (cdeftable[*s]!=0) {
dbg printf("Found char definition %d {%s} \n",*s,s);
nrep++;
dfn = UC tex_findchardef(*s);
memmove(s+strlen(SC dfn)-1,s,strlen(SC s)+1);
strncpy(SC s,SC dfn,strlen(SC dfn));
s--;
}
}
dbg printf("MACOR IN {%s} \n",in);
dbg printf("MACOR CODE {%s} \n",out);
}
tex_presave()
{
int i;
deftable *dt;
FILE *fout;
mdeftable *mdt;
char *workarea;
/* Save all defined features possible */
fout = fopen(gledir("inittex.ini"),WRITE_BIN);
if (fout==NULL) gprint("Could not open inittex.ini file \n");
fwrite(fontfam,sizeof(int),16*4,fout);
fwrite(fontfamsz,sizeof(double),16*4,fout);
fwrite(chr_mathcode,sizeof(char),256,fout);
for (i=0;i<HASHSIZE;i++) {
for (dt = def_hashtab[i]; dt != NULL; dt = dt->next) {
fwrite(&i,sizeof(i),1,fout);
fwrite(&dt->npm,sizeof(i),1,fout);
fsendstr(dt->name,fout);
fsendstr(dt->defn,fout);
}
}
i = 0x0fff; fwrite(&i,sizeof(i),1,fout);
for (i=0;i<HASHSIZE;i++) {
for (mdt = mdef_hashtab[i]; mdt != NULL; mdt = mdt->next) {
fwrite(&i,sizeof(i),1,fout);
fwrite(&mdt->defn,sizeof(i),1,fout);
fsendstr(mdt->name,fout);
}
}
i = 0x0fff; fwrite(&i,sizeof(i),1,fout);
for (i=0;i<256;i++) fsendstr(cdeftable[i],fout);
fclose(fout);
}
/*----------------------------------------------------------------------*/
fgetvstr(char **s,FILE *fmt)
{
int i;
i = fgetc(fmt);
if (i==0) return;
*s = myalloc(i+1);
fread(*s,1,i,fmt);
*(*s+i) = 0;
}
fgetcstr(char s[],FILE *fmt)
{
int i;
i = fgetc(fmt);
if (i==0) return;
fread(s,1,i,fmt);
s[i] = 0;
}
fsendstr(char *s,FILE *fout)
{
if (s==NULL) {
fputc(0,fout);
return;
}
fputc(strlen(s),fout);
fwrite(s,1,strlen(s),fout);
}
tex_preload()
{
int i,j;
deftable *dt;
FILE *fout;
mdeftable *mdt;
char *workarea;
char str1[80],str2[80];
/* reload all defined features */
fout = fopen(gledir("inittex.ini"),READ_BIN);
if (fout==NULL) {gprint("Could not open inittex.ini file \n"); return;}
fread(fontfam,sizeof(int),16*4,fout);
fread(fontfamsz,sizeof(double),16*4,fout);
fread(chr_mathcode,sizeof(char),256,fout);
for (; (fread(&i,sizeof(i),1,fout)), i != 0x0fff;) {
fread(&j,sizeof(j),1,fout);
fgetcstr(str1,fout); fgetcstr(str2,fout);
tex_def(str1,str2,j);
}
for (; (fread(&i,sizeof(i),1,fout)), i != 0x0fff;) {
fread(&j,sizeof(j),1,fout);
fgetcstr(str1,fout);
tex_mathdef(str1,j);
}
for (i=0;i<256;i++) fgetvstr(&cdeftable[i],fout);
fclose(fout);
}